/*
 * Copyright (c) 2018-2999 湖南洛云网络科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yami.shop.bean.dto.FormExcelDto;
import com.yami.shop.bean.enums.FlowTimeTypeEnum;
import com.yami.shop.bean.enums.FormItemEnum;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.FormExcelParam;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.dao.FormMapper;
import com.yami.shop.service.FormService;
import lombok.AllArgsConstructor;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 * @author lgh on 2018/11/26.
 */
@Service
@AllArgsConstructor
public class FormServiceImpl extends ServiceImpl<FormMapper, Form> implements FormService {

    private final FormMapper formMapper;
    private final Boolean TRUE = true;


    @Override
    @Cacheable(cacheNames = "formItem", key = "'formItem:' + #type")
    public List<FormItem> getFormItem(Integer type) {
        //type 1:平台端  2：商家端
        //获取所有的枚举对象
        FormItemEnum[] formItemEnums = FormItemEnum.allEnum();
        FormItem formItem = null;
        List<FormItem> formItemList = Lists.newArrayList();
        //把枚举的数据保存到集合中
        for (FormItemEnum formItemEnum:formItemEnums){
            if (formItemEnum.getType() == 0 || Objects.equals(formItemEnum.getType(), type)){
                formItem = new FormItem();
                formItem.setId(formItemEnum.value());
                formItem.setValue(formItemEnum.getName());
                formItemList.add(formItem);
            }
        }
        return formItemList;
    }

    @Override
    public void formExcel(Long formId, HttpServletResponse response) {
        FormExcelParam formExcelParam = new FormExcelParam();
        List<FormExcelDto> formExcelDtoList = Lists.newArrayList();
        // 获取生成报表的数据信息
        getFormExcel(formId,formExcelParam,formExcelDtoList);
        //生成报表
        excel(formExcelParam,formExcelDtoList,response);
    }

    /**
     * 拼接报表需要查询的数据字段，并对查询返回的数据进行处理
     * @param formId 需要生成数据的报表的id
     * @param formExcelParam 报表设置的参数
     * @param formExcelDtoList 处理后的报表数据
     */
    private void getFormExcel(Long formId,FormExcelParam formExcelParam,List<FormExcelDto> formExcelDtoList){
        Form form = formMapper.selectById(formId);
        formExcelParam.setShopId(form.getShopId());
        formExcelParam.setFormName(form.getFormName());
        formExcelParam.setTimeType(form.getTimeType());
        //设置开始/结束时间
        if (form.getTimeFormat() == 1){
            // 自定义时间查询，直接set开始和结束时间
            if (form.getTimeType() == 1) {
                formExcelParam.setStartTime(DateUtil.beginOfDay(form.getStartTime()));
                formExcelParam.setEndTime(DateUtil.endOfDay(form.getEndTime()));
            } else if (form.getTimeType() == 2) {
                formExcelParam.setStartTime(DateUtil.beginOfWeek(form.getStartTime()));
                formExcelParam.setEndTime(DateUtil.endOfWeek(form.getEndTime()));
            } else {
                formExcelParam.setStartTime(DateUtil.beginOfMonth(form.getStartTime()));
                formExcelParam.setEndTime(DateUtil.endOfMonth(form.getEndTime()));
            }
        }else {
            //获取当天的开始时间
            Calendar calendar = DateUtil.beginOfDay(Calendar.getInstance());
            int timeRamge = form.getTimeRamge()-1;
            //当天开始时间减去报表模板的时间范围，得到报表数据的开始时间
            if (formExcelParam.getTimeType() == 1){
                calendar.add(Calendar.DAY_OF_YEAR,-timeRamge);
            }else if (formExcelParam.getTimeType() == 2){
                //设置周一为每周的开始日期
                calendar.setFirstDayOfWeek(Calendar.MONDAY);
                calendar.add(Calendar.WEEK_OF_YEAR,-timeRamge);
                //时间周期-周，开始时间为该周的周一
                calendar.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY);
            }else {
                calendar.add(Calendar.MONTH,-timeRamge);
                //时间周期-月，开始时间为该月的1号
                calendar.set(Calendar.DAY_OF_MONTH,1);
            }
            formExcelParam.setStartTime(calendar.getTime());
            //结束时间为当前时间
            formExcelParam.setEndTime(new Date());
        }
        //获取报表列名称的集合
        List<String> formItemNameList = Lists.newArrayList();
        //模板中选择的报表指标
        List<Integer> formItemIdList = Lists.newArrayList();
        //报表第一项数据为时间
        formItemNameList.add("日期");
        String[] ids = form.getFormItemIds().split(",");
        int id = 0;
        Boolean isTrue = true;
        //根据报表模板中的指标数据，设置需要查询的参数和报表的列名
        for (String idStr:ids){
            setColumn(formExcelParam, formItemNameList, formItemIdList, idStr);
//            }else if (FormItemEnum.VISIT.value() == id){
//                //浏览量
//                formExcelParam.setVisit(TRUE);
//                formItemNameList.add(FormItemEnum.VISIT.getName());
//            }else if (FormItemEnum.LOSS_RATE.value() == id){
//                //跳失率
//                formExcelParam.setLossRate(TRUE);
//                formItemNameList.add(FormItemEnum.LOSS_RATE.getName());
//            }else if (FormItemEnum.AVERAGE_VISIT.value() == id){
//                //平均浏览量
//                formExcelParam.setVisit(TRUE);
//                formExcelParam.setVisitUser(TRUE);
//                formItemNameList.add(FormItemEnum.LOSS_RATE.getName());
//            }else if (FormItemEnum.AVERAGE_STOP_TIME.value() == id){
//                //平均停留时长（秒）
//                formExcelParam.setStopTime(TRUE);
//                formExcelParam.setVisitUser(TRUE);
//                formItemNameList.add(FormItemEnum.AVERAGE_STOP_TIME.getName());
//            }else if (FormItemEnum.SHARE_VISIT_USER.value() == id){
//                //分享访问人数
//                formExcelParam.setShareVisitUser(TRUE);
//                formItemNameList.add(FormItemEnum.SHARE_VISIT_USER.getName());
//            }else if (FormItemEnum.SHARE_VISIT_NUM.value() == id){
//                //分享访问次数
//                formExcelParam.setShareVisitNum(TRUE);
//                formItemNameList.add(FormItemEnum.SHARE_VISIT_NUM.getName());
//            }else if (FormItemEnum.VISIT_USER.value() == id){
//                //访客数
//                formExcelParam.setVisitUser(TRUE);
//                formItemNameList.add(FormItemEnum.VISIT_USER.getName());
//            }else if (FormItemEnum.VISIT_PAY_RATE.value() == id){
//                //访问-支付转化率
//                formExcelParam.setVisitPayUser(TRUE);
//                formExcelParam.setVisitUser(TRUE);
//                formItemNameList.add(FormItemEnum.VISIT_PAY_RATE.getName());
//            }else if (FormItemEnum.VISIT_PLACE_ORDER_RATE.value() == id){
//                //访问-下单转化率
//                formExcelParam.setVisitPlaceOrderUser(TRUE);
//                formExcelParam.setVisitUser(TRUE);
//                formItemNameList.add(FormItemEnum.VISIT_PLACE_ORDER_RATE.getName());
//            }
        }
//        //获取报表的店铺数据信息
//        List<FormExcelDto> shopOrderInfoList = null;
//        if (formExcelParam.isShopInfo()){
//            shopOrderInfoList = formMapper.getShopFormInfoList(formExcelParam);
//        }
//        //获取报表的数据分析信息
//        List<FormExcelDto> analysisList = null;
//        if (formExcelParam.isAnalysisList()){
//            analysisList = formMapper.getAnalysisListInfoList(formExcelParam);
//        }
        //获取报表的店铺数据信息
        List<FormExcelDto> shopOrderInfoList = formMapper.getShopFormInfoList(formExcelParam);
        //其他扩展的报表数据（待开发）
        //设置报表列名称的数组
        formExcelParam.setFormItemNameList(formItemNameList.toArray(new String[]{}));
        //设置报表指标的id数组
        formExcelParam.setFormItemIdList(formItemIdList);
        // 数据库中获取的报表数据转换成map
        Map<Date, FormExcelDto> dateFormExcelDtoToDateMap = null;
        Map<String, FormExcelDto> dateFormExcelDtoToStringMap = null;
        //报表数据分析相关功能
//        Map<Date, FormExcelDto> analysisListAsDateMap = null;
//        Map<Integer, FormExcelDto> analysisListAsToIntegerMap = null;
        if (formExcelParam.getTimeType() == 1){
            //时间周期-日 ------------ 每日的时间为key
//            if (CollUtil.isNotEmpty(shopOrderInfoList)){
//                dateFormExcelDtoToDateMap = shopOrderInfoList.stream().collect(Collectors.toMap(FormExcelDto::getInfoTime, formExcelDto -> formExcelDto));
//            }else if (CollUtil.isNotEmpty(analysisList)){
//                analysisListAsDateMap = analysisList.stream().collect(Collectors.toMap(FormExcelDto::getInfoTime, formExcelDto -> formExcelDto));
//            }
            dateFormExcelDtoToDateMap = shopOrderInfoList.stream().collect(Collectors.toMap(FormExcelDto::getInfoTime, formExcelDto -> formExcelDto));
        } else {
            //时间周期-周/月 ------------ 周数（该年的第几周）/月数  为key
//            if (CollUtil.isNotEmpty(shopOrderInfoList)){
//                dateFormExcelDtoToIntegerMap = shopOrderInfoList.stream().collect(Collectors.toMap(FormExcelDto::getWeedOrMonth, formExcelDto -> formExcelDto));
//            }else if (CollUtil.isNotEmpty(analysisList)){
//                analysisListAsToIntegerMap = analysisList.stream().collect(Collectors.toMap(FormExcelDto::getWeedOrMonth, formExcelDto -> formExcelDto));
//            }
            dateFormExcelDtoToStringMap = shopOrderInfoList.stream().collect(Collectors.toMap(FormExcelDto::getWeedOrMonth, formExcelDto -> formExcelDto));
        }
        //根据查询得到的数据，拼接成报表的数据
        Date date = formExcelParam.getStartTime();
        while(true){
            // 循环的时间大于结束时间 ==》 退出循环
            if (date.getTime()>formExcelParam.getEndTime().getTime()){
                break;
            }
            Map<String,Object> dateInfo = this.getDateInfoByTimeAndType(date,formExcelParam.getTimeType());
            FormExcelDto formExcelDto = null;
            if (formExcelParam.getTimeType() == 1){
                //时间周期-日
                formExcelDto = dateFormExcelDtoToDateMap.get((Date) dateInfo.get("day"));
            }else{
                //时间周期-周/月
                String weekOrMonth = (String) dateInfo.get("weekOrMonth");
                formExcelDto = dateFormExcelDtoToStringMap.get(weekOrMonth);
            }
            if (Objects.isNull(formExcelDto)){
                formExcelDto = new FormExcelDto();
            }else {
                System.out.println();
            }
            // 设置报表中第一列的时间数据
            formExcelDto.setFormatTime((String) dateInfo.get("dateTime"));
            // 拼接后的数据放入集合中
            formExcelDtoList.add(formExcelDto);
            //设置下轮循环的开始时间
            date = (Date) dateInfo.get("date");
        }
    }

    private void setColumn(FormExcelParam formExcelParam, List<String> formItemNameList, List<Integer> formItemIdList, String idStr) {
        int id = Integer.parseInt(idStr);
        formItemIdList.add(id);
        if (FormItemEnum.CUSTOMER_UNIT_PRICE.value() == id) {
            //客单价 (支付金额/支付订单数)
            formExcelParam.setPayAmount(TRUE);
            formExcelParam.setPayOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.CUSTOMER_UNIT_PRICE.getName());
        }else if (FormItemEnum.TOTAL_TRANSACTION_AMOUNT.value() == id) {
            //总金额 === 支付金额
            formExcelParam.setPayAmount(TRUE);
            formItemNameList.add(FormItemEnum.TOTAL_TRANSACTION_AMOUNT.getName());
        }else if (FormItemEnum.SELF_OPERATED_CUSTOMER_UNIT_PRICE.value() == id){
            //自营客单价 (自营金额/自营订单数)
            formExcelParam.setSelfOperatedAmount(TRUE);
            formExcelParam.setSelfOperatedOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.SELF_OPERATED_CUSTOMER_UNIT_PRICE.getName());
        }else if (FormItemEnum.SELF_OPERATED_AMOUNT.value() == id){
            //自营金额
            formExcelParam.setSelfOperatedAmount(TRUE);
            formItemNameList.add(FormItemEnum.SELF_OPERATED_AMOUNT.getName());
        }else if (FormItemEnum.SELF_OPERATED_ORDER_NUMS.value() == id){
            //自营订单数
            formExcelParam.setSelfOperatedOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.SELF_OPERATED_ORDER_NUMS.getName());
        }else if (FormItemEnum.SELF_OPERATED_PRODUCT_NUMS.value() == id){
            //自营商品数
            formExcelParam.setSelfOperatedProductNums(TRUE);
            formItemNameList.add(FormItemEnum.SELF_OPERATED_PRODUCT_NUMS.getName());
        }else if (FormItemEnum.ORDER_AMOUNT.value() == id){
            //下单金额
            formExcelParam.setOrderAmount(TRUE);
            formItemNameList.add(FormItemEnum.ORDER_AMOUNT.getName());
        }else if (FormItemEnum.USER_NUMS.value() == id){
            //下单人数
            formExcelParam.setUserNums(TRUE);
            formItemNameList.add(FormItemEnum.USER_NUMS.getName());
        }else if (FormItemEnum.ORDER_NUMS.value() == id){
            //下单笔数
            formExcelParam.setOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.ORDER_NUMS.getName());
        }else if (FormItemEnum.PRODUCT_NUMS.value() == id){
            //下单商品数
            formExcelParam.setProductNums(TRUE);
            formItemNameList.add(FormItemEnum.PRODUCT_NUMS.getName());
        }else if (FormItemEnum.PAY_AMOUNT.value() == id){
            //支付金额
            formExcelParam.setPayAmount(TRUE);
            formItemNameList.add(FormItemEnum.PAY_AMOUNT.getName());
        }else if (FormItemEnum.PAY_USER_NUMS.value() == id){
            //支付人数
            formExcelParam.setPayUserNums(TRUE);
            formItemNameList.add(FormItemEnum.PAY_USER_NUMS.getName());
        }else if (FormItemEnum.PAY_ORDER_NUMS.value() == id){
            //支付订单数
            formExcelParam.setPayOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.PAY_ORDER_NUMS.getName());
        }else if (FormItemEnum.PAY_PRODUCT_NUMS.value() == id){
            //支付商品数
            formExcelParam.setPayProductNums(TRUE);
            formItemNameList.add(FormItemEnum.PAY_PRODUCT_NUMS.getName());
        }else if (FormItemEnum.SUCCESS_REFUND_AMOUNT.value() == id){
            //成功退款金额
            formExcelParam.setRefundAmount(TRUE);
            formItemNameList.add(FormItemEnum.SUCCESS_REFUND_AMOUNT.getName());
        }else if (FormItemEnum.REFUND_ORDER_NUMS.value() == id){
            //退款订单数量
            formExcelParam.setRefundOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.REFUND_ORDER_NUMS.getName());
        }else if (FormItemEnum.ORDER_TO_PAY_RATE.value() == id){
            //下单-支付转化率 （支付订单数量/下单订单数量）
            formExcelParam.setPayOrderNums(TRUE);
            formExcelParam.setOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.ORDER_TO_PAY_RATE.getName());
        }else if (FormItemEnum.REFUND_RATE.value() == id){
            //退款率（退款订单数量/订单数量）
            formExcelParam.setRefundOrderNums(TRUE);
            formExcelParam.setPayOrderNums(TRUE);
            formItemNameList.add(FormItemEnum.REFUND_RATE.getName());
        }
    }

    /**
     * 生成报表
     * @param formExcelParam 报表设置的参数
     * @param formExcelDtoList 报表的数据
     * @param response
     */
    public void excel(FormExcelParam formExcelParam,List<FormExcelDto> formExcelDtoList, HttpServletResponse response) {
        List<Integer> formItemIdList = formExcelParam.getFormItemIdList();
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter();
        // 报表列名称数组
        String[] hearder = formExcelParam.getFormItemNameList();
        Sheet sheet = writer.getSheet();
        //时间列的宽度
        sheet.setColumnWidth(0, 20 * 256);
        //剩余列的宽度
        for (int i = 1;i <= formExcelParam.getFormItemNameList().length; i++){
            sheet.setColumnWidth(i, 10 * 256);
        }
        //设置报表名称
        writer.merge(hearder.length - 1, formExcelParam.getFormName());
        writer.writeRow(Arrays.asList(hearder));
        int row = 1;
        //循环插入每一行的数据
        for(FormExcelDto formExcelDto:formExcelDtoList){
            int firstRow = ++row;
            int lastRow = firstRow;
            int col = -1;
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getFormatTime());
            if (formItemIdList.contains(FormItemEnum.CUSTOMER_UNIT_PRICE.value())) {
                //客单价
                double customerUnitReice = Arith.div(formExcelDto.getPayAmount(),formExcelDto.getPayOrderNums());
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, customerUnitReice);
            }
            if (formItemIdList.contains(FormItemEnum.TOTAL_TRANSACTION_AMOUNT.value())) {
                //总金额/支付金额
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getPayAmount());
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_CUSTOMER_UNIT_PRICE.value())){
                //自营客单价 (自营金额/自营订单数)
                double customerUnitReice  = Arith.div(formExcelDto.getSelfOperatedAmount(),formExcelDto.getSelfOperatedOrderNums());
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, customerUnitReice);
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_AMOUNT.value())){
                //自营金额
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getSelfOperatedAmount());
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_ORDER_NUMS.value())){
                //自营订单数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getSelfOperatedOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_PRODUCT_NUMS.value())){
                //自营商品数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getSelfOperatedProductNums());
            }
            if (formItemIdList.contains(FormItemEnum.ORDER_AMOUNT.value())){
                //下单金额
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getOrderAmount());
            }
            if (formItemIdList.contains(FormItemEnum.USER_NUMS.value())){
                //下单人数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getUserNums());
            }
            if (formItemIdList.contains(FormItemEnum.ORDER_NUMS.value())){
                //下单笔数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.PRODUCT_NUMS.value())){
                //下单商品数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getProductNums());
            }
            if (formItemIdList.contains(FormItemEnum.PAY_AMOUNT.value())){
                //支付金额
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getPayAmount());
            }
            if (formItemIdList.contains(FormItemEnum.PAY_USER_NUMS.value())){
                //支付人数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getPayUserNums());
            }
            if (formItemIdList.contains(FormItemEnum.PAY_ORDER_NUMS.value())){
                //支付订单数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getPayOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.PAY_PRODUCT_NUMS.value())){
                //支付商品数
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getPayProductNums());
            }
            if (formItemIdList.contains(FormItemEnum.SUCCESS_REFUND_AMOUNT.value())){
                //成功退款金额
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getRefundAmount());
            }
            if (formItemIdList.contains(FormItemEnum.REFUND_ORDER_NUMS.value())){
                //退款订单数量
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, formExcelDto.getRefundOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.ORDER_TO_PAY_RATE.value())){
                //下单-支付转化率 （支付订单数量/下单订单数量）
                double orderPayRate = 0.0;
                orderPayRate = Arith.round(Arith.mul(Arith.div(formExcelDto.getPayOrderNums(), formExcelDto.getOrderNums()), 100), 2);
                mergeIfNeed(writer, firstRow, lastRow, ++col, col,orderPayRate + "%");
            }
            if (formItemIdList.contains(FormItemEnum.REFUND_RATE.value())){
                //退款率
                double refundRate = Arith.round(Arith.mul(Arith.div(formExcelDto.getRefundOrderNums(), formExcelDto.getPayOrderNums()), 100), 2);
                mergeIfNeed(writer, firstRow, lastRow, ++col, col,refundRate + "%");
            }
        }
        writeExcel(response, writer);
    }
    /**
     * 如果需要合并的话，就合并
     */
    @Override
    public void mergeIfNeed(ExcelWriter writer, int firstRow, int lastRow, int firstColumn, int lastColumn, Object content) {
        if (lastRow - firstRow > 0 || lastColumn - firstColumn > 0) {
            writer.merge(firstRow, lastRow, firstColumn, lastColumn, content, false);
        } else {
            writer.writeCellValue(firstColumn, firstRow, content);
        }

    }
    @Override
    public void writeExcel(HttpServletResponse response, ExcelWriter writer) {
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=1.xls");

        ServletOutputStream servletOutputStream = null;
        try {
            servletOutputStream = response.getOutputStream();
            writer.flush(servletOutputStream);
            servletOutputStream.flush();
        } catch (IORuntimeException | IOException e) {
            e.printStackTrace();
        } finally {
            writer.close();
            try {
                if (servletOutputStream != null) {
                    servletOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<Form> getRecommendFormList() {
        PageParam<Form> page = new PageParam();
        page.setSize(Long.MAX_VALUE);
        IPage<Form> defaultFormPage = formMapper.getRecommendFormPage(page, new Form());
        List<Form> formList = defaultFormPage.getRecords();
        List<FormItem> formItem = this.getFormItem(2);
        Map<Integer, FormItem> formItemMap = formItem.stream().collect(Collectors.toMap(FormItem::getId,formItemNew -> formItemNew));
        List<FormItem> formItemList = null;
        for (Form form: formList){
            formItemList = Lists.newArrayList();
            for (String id: form.getFormItemIds().split(",")){
                formItemList.add(formItemMap.get(Integer.valueOf(id)));
            }
            form.setFormItemList(formItemList);
        }
        return formList;
    }

    @Override
    @CacheEvict(cacheNames = "form", key = "'defaultForm'")
    public void removeCache() {
    }

    @Override
    public IPage<Form> getRecommendFormPage(PageParam<Form> page, Form form) {
        return formMapper.getRecommendFormPage(page,form);
    }

    /**
     * 根据时间和时间周期，获取报表中的时间数据以及下一次循环的开始时间数据
     * @param time
     * @param type
     * @return
     */
    private Map<String,Object> getDateInfoByTimeAndType(Date time, Integer type){
        //date ： 下次循环的开始时间
        //day/weekOrMonth ：用于map对象获取数据时，所需的key的值
        //dateTime ： 时间格式化后，在报表中显示的时间数据（报表第一列的时间字符串）
        Map<String,Object> map = Maps.newHashMap();
        if (type == 1){
            //时间周期：日
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            map.put("day",time);
            map.put("date",DateUtil.offset(time, DateField.DAY_OF_MONTH, 1));
            map.put("dateTime",simpleDateFormat.format(time));
        }else if (type == 2){
            //时间周期：周
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            //设置周的开始时间为周一
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            calendar.setTime(time);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            // 获取该周，周一零时的时间（周的开始时间）
            Date mondayTime = calendar.getTime();
            //把开始时间由该周一切换成下周一，为下次循环的周一时间
            map.put("date",DateUtil.offset(mondayTime, DateField.DAY_OF_MONTH, 7));
            String dateTime = "";
            if (time.getTime() > mondayTime.getTime()){
                dateTime = simpleDateFormat.format(time);
            }else {
                dateTime = simpleDateFormat.format(mondayTime);
            }
            //设置周的结束时间为周日
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
            //周的开始时间与结束时间拼接
            dateTime = dateTime + "~" + simpleDateFormat.format(calendar.getTime());
            map.put("weekOrMonth",calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.WEEK_OF_YEAR) - 1));
            map.put("dateTime",dateTime);
        }else if (type == 3){
            //时间周期：月
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-M");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(time);
            calendar.set(Calendar.DAY_OF_MONTH,1);
            String date = simpleDateFormat.format(calendar.getTime());
            calendar.add(Calendar.MONTH, 1);
            map.put("date",calendar.getTime());
            map.put("weekOrMonth",date);
            map.put("dateTime",date);
        }
        return map;
    }
}
